summaryrefslogtreecommitdiff
path: root/app/api/auth/[...nextauth]
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-03-25 15:55:45 +0900
committerjoonhoekim <26rote@gmail.com>2025-03-25 15:55:45 +0900
commit1a2241c40e10193c5ff7008a7b7b36cc1d855d96 (patch)
tree8a5587f10ca55b162d7e3254cb088b323a34c41b /app/api/auth/[...nextauth]
initial commit
Diffstat (limited to 'app/api/auth/[...nextauth]')
-rw-r--r--app/api/auth/[...nextauth]/route.ts111
1 files changed, 111 insertions, 0 deletions
diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts
new file mode 100644
index 00000000..609a63d7
--- /dev/null
+++ b/app/api/auth/[...nextauth]/route.ts
@@ -0,0 +1,111 @@
+// (1) next-auth에서 필요한 타입들을 import
+import NextAuth, {
+ NextAuthOptions, // authOptions에 쓸 타입
+ Session,
+ User
+} from 'next-auth'
+import { JWT } from "next-auth/jwt"
+
+import CredentialsProvider from 'next-auth/providers/credentials'
+
+import { verifyOtp } from '@/lib/users/verifyOtp'
+
+// 1) 모듈 보강 선언
+declare module "next-auth" {
+ /**
+ * Session 객체를 확장
+ */
+ interface Session {
+ user: {
+ /** 우리가 필요로 하는 user id */
+ id: string
+
+ // 기본적으로 NextAuth가 제공하는 name/email/image 필드
+ name?: string | null
+ email?: string | null
+ image?: string | null
+ companyId?: number | null
+ domain?: string | null
+
+ }
+ }
+
+ /**
+ * User 객체를 확장
+ */
+ interface User {
+ id: string
+ imageUrl?: string | null
+ companyId?: number | null
+ domain?: string | null
+ // 필요한 필드를 추가로 선언 가능
+ }
+}
+
+// (2) authOptions에 NextAuthOptions 타입 지정
+export const authOptions: NextAuthOptions = {
+ providers: [
+ CredentialsProvider({
+ name: 'Credentials',
+ credentials: {
+ email: { label: 'Email', type: 'text' },
+ code: { label: 'OTP code', type: 'text' },
+ },
+ async authorize(credentials, req) {
+ const { email, code } = credentials ?? {}
+
+ // OTP 검증
+ const user = await verifyOtp(email ?? '', code ?? '')
+ if (!user) {
+ return null
+ }
+
+ return {
+ id: String(user.id ?? email ?? "dts"),
+ email: user.email,
+ imageUrl: user.imageUrl ?? null,
+ name: user.name, // DB에서 가져온 실제 이름
+ companyId: user.companyId, // DB에서 가져온 실제 이름
+ domain: user.domain, // DB에서 가져온 실제 이름
+ }
+ },
+ })
+ ],
+ // (3) session.strategy는 'jwt'가 되도록 선언
+ // 필요하다면 as SessionStrategy 라고 명시해줄 수도 있음
+ // 예) strategy: 'jwt' as SessionStrategy
+ session: {
+ strategy: 'jwt',
+ },
+ callbacks: {
+ // (4) 콜백에서 token, user, session 등의 타입을 좀 더 명시해주고 싶다면 아래처럼 destructuring에 제네릭/타입 지정
+ async jwt({ token, user }: { token: JWT; user?: User }) {
+ if (user) {
+ token.id = user.id
+ token.email = user.email
+ token.name = user.name
+ token.companyId = user.companyId
+ token.domain = user.domain
+ ; (token as any).imageUrl = (user as any).imageUrl
+ }
+ return token
+ },
+ async session({ session, token }: { session: Session; token: JWT }) {
+ if (token) {
+ session.user = {
+ id: token.id as string,
+ email: token.email as string,
+ name: token.name as string,
+ domain: token.domain as string,
+ companyId: token.companyId as number,
+ image: (token as any).imageUrl ?? null
+ }
+ }
+ return session
+ },
+ },
+}
+
+const handler = NextAuth(authOptions)
+
+export { handler as GET, handler as POST } \ No newline at end of file